package survivial;

import java.util.Random;

import cpw.mods.fml.common.registry.GameRegistry;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemHoe;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemSword;
import net.minecraft.item.ItemTool;
import net.minecraft.item.crafting.FurnaceRecipes;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityFurnace;
import net.minecraft.util.Vec3;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeDirection;
import net.minecraftforge.common.ForgeDummyContainer;

public class TileEntityCampfire extends TileEntityFurnace implements ISidedInventory
{
	static
	{
		addMapping(TileEntityCampfire.class, "Campfire");

		TileEntityCampfireRenderer tecr = new TileEntityCampfireRenderer();
		TileEntityRenderer.instance.specialRendererMap.put(TileEntityCampfire.class, tecr);
		tecr.setTileEntityRenderer(TileEntityRenderer.instance);
	}

	private boolean _isRegisteredForUpdates = false;

	@Override
	public boolean isInvalid()
	{
		boolean isInvalid = super.isInvalid();

		if (!_isRegisteredForUpdates && !isInvalid)
		{ // Schedule ourselves for
			// updates
			_isRegisteredForUpdates = true;
			Survivial.Ticker.RegisterEntity(this);
		}

		return isInvalid;
	}

	private boolean canSmelt()
	{
		if (this.furnaceItemStacks[0] == null)
		{
			return true; // false;
		}
		else
		{
			return true;
			/*
			 * ItemStack itemstack =
			 * FurnaceRecipes.smelting().getSmeltingResult(
			 * this.furnaceItemStacks[0]); if (itemstack == null) return false;
			 * if (this.furnaceItemStacks[2] == null) return true; if
			 * (!this.furnaceItemStacks[2].isItemEqual(itemstack)) return false;
			 * int result = furnaceItemStacks[2].stackSize +
			 * itemstack.stackSize; return (result <= getInventoryStackLimit()
			 * && result <= itemstack.getMaxStackSize());
			 */
		}
	}

	private ItemStack[] furnaceItemStacks = new ItemStack[3];

	private Boolean _isFirstUpdate = true;

	static private Random _rand = new Random();

	public void UpdateFlames()
	{
		if (isBurning() && !IsDisabled)
			_UpdateFlames(Survivial.getWorld(), xCoord, yCoord, zCoord);
	}

	private long _timeForNextLightVariation;
	private int _currentBlockID;
	private float _flameIntensity = 5;

	private void _UpdateFlames(World world, int xc, int yc, int zc)
	{
		long timeNow = Survivial.SystemTime;

		if (timeNow > _timeForNextLightVariation)
		{
			_timeForNextLightVariation = timeNow + 1000; // (int)(2000.0 *
															// _rand.nextDouble());

			int blockID = _currentBlockID;
			int burnTimeLeft = furnaceBurnTime;
			ItemStack fuelStack = furnaceItemStacks[1];

			if (fuelStack != null)
			{
				int itemBurn = getItemBurnTime(fuelStack);
				burnTimeLeft += (itemBurn * fuelStack.stackSize);
			}
			if (burnTimeLeft >= 700)
			{
				_flameIntensity = 7f + (burnTimeLeft / 1100f);
				if (_flameIntensity > 8)
					_flameIntensity = 8;
				blockID = Survivial.campfireBright.blockID;
			}
			if (burnTimeLeft >= 600 & burnTimeLeft < 700)
			{
				_flameIntensity = 6;
				blockID = Survivial.campfireBrightLow.blockID;
			}

			if (burnTimeLeft >= 500 & burnTimeLeft < 600)
			{
				_flameIntensity = 4.5F;
				blockID = Survivial.campfireMedium.blockID;
			}

			if (burnTimeLeft >= 400 & burnTimeLeft < 500)
			{
				_flameIntensity = 3;
				blockID = Survivial.campfireMediumLow.blockID;
			}
			if (burnTimeLeft < 400)
			{
				blockID = (burnTimeLeft >= 300) ? Survivial.campfireDim.blockID : Survivial.campfireDimLow.blockID;
				_flameIntensity = (burnTimeLeft / 160f);
			}
			_currentBlockID = world.getBlockId(xc, yc, zc);
			if (_currentBlockID != blockID)
			{
				world.setBlock(xc, yc, zc, blockID, 0, 3);
			}

		}

		double velX = -1.0 + 2.0 * _rand.nextDouble();
		double velZ = -1.0 + 2.0 * _rand.nextDouble();
		double windMag = 0.004;

		int iterations = (int) (_flameIntensity * _rand.nextFloat());
		if (iterations < 1)
		{
			float threshold = (_flameIntensity >= 0.4f) ? 0.5f : 0.8f;

			if (_rand.nextFloat() > threshold)
				iterations = 1;
		}
		// if (iterations < 1)
		// iterations = 1;

		for (int i = 0; i < iterations; i++)
		{
			// int l = par1World.getBlockMetadata(par2, par3, par4);
			double x = xc + 0.3 + (_rand.nextDouble() * 0.4); // 2.5F;
			double y = yc + 0.1 + (_rand.nextDouble() * 0.07 * _flameIntensity); // +
																					// (0.022
																					// *
																					// i);
			double z = zc + 0.3 + (_rand.nextDouble() * 0.4); // 2.5F;
			double velX2 = -0.5 + 1.0 * _rand.nextDouble();
			double velZ2 = -0.5 + 1.0 * _rand.nextDouble();

			double velY = 0.005 * _flameIntensity; // 0.01 * rand.nextDouble();
			if (_rand.nextFloat() > 0.9)
				velY = 0.05 * (_rand.nextDouble() * 0.2 * _flameIntensity);

			world.spawnParticle("smoke", x, y + 0.5, z, windMag * (velX + velX2), 0.0D, windMag * (velZ + velZ2));
			world.spawnParticle("flame", x, y, z, windMag * (velX + velX2), velY, windMag * (velZ + velZ2));
			
		}

		// now create Smoke Blocks
		int xo = -1 + _rand.nextInt(3);
		int zo = -1 + _rand.nextInt(3);
		int xi = xc + xo;
		int zi = zc + zo;
		int yi = yc + 1;
		
		int blockID = world.getBlockId(xi, yi, zi);
		if (blockID <= 0)
		{
			//world.setBlock(xi, yi, zi, Survivial.smoke.blockID, 0, 3); 
		}

	}

	public boolean IsDisabled;

	public void updateEntity()
	{
		if (isBurning())
		{
			// BlockCampfire.UpdateFlames(worldObj, xCoord, yCoord, zCoord,
			// _rand);
		}
		for (int i = 0; i < 3; i++)
		{
			furnaceItemStacks[i] = getStackInSlot(i);
		}

		// super.updateEntity();

		boolean flag = this.furnaceBurnTime > 0;
		boolean flag1 = false;

		if (this.furnaceBurnTime > 0)
		{
			--this.furnaceBurnTime;
		}

		if (!this.worldObj.isRemote)
		{
			if (this.furnaceBurnTime <= 0 && this.canSmelt())
			{
				this.currentItemBurnTime = this.furnaceBurnTime = getItemBurnTime(this.furnaceItemStacks[1]);

				if (this.furnaceBurnTime > 0)
				{
					flag1 = true;

					ItemStack fuel = furnaceItemStacks[1];
					if (fuel != null)
					{
						--fuel.stackSize;

						if (fuel.stackSize <= 0)
						{
							ItemStack container = fuel.getItem().getContainerItemStack(furnaceItemStacks[1]);
							this.furnaceItemStacks[1] = container;
							setInventorySlotContents(1, null);

						}
					}
				}
			}

			if (this.isBurning() && this.canSmelt())
			{
				++this.furnaceCookTime;

				if (this.furnaceCookTime == 200)
				{
					this.furnaceCookTime = 0;
					this.smeltItem();
					flag1 = true;
				}
			}
			else
			{
				this.furnaceCookTime = 0;
			}

			if (_isFirstUpdate || flag != this.furnaceBurnTime > 0)
			{
				if (_isFirstUpdate)
					Survivial.Ticker.RegisterEntity(this);
				_isFirstUpdate = false;
				flag1 = true;
				BlockCampfire.updateCampfireBlockState(this.furnaceBurnTime > 0, this.worldObj, this.xCoord, this.yCoord, this.zCoord);
			}
		}

		if (flag1)
		{
			this.onInventoryChanged();
		}
	}

	/*
	 * public String getInvName() { return this.isInvNameLocalized() ?
	 * this.field_94130_e : "container.campfire"; }
	 * 
	 * public boolean isInvNameLocalized() { return this.field_94130_e != null
	 * && this.field_94130_e.length() > 0; }
	 * 
	 * public void setGuiDisplayName(String par1Str) { this.field_94130_e =
	 * par1Str; } private String field_94130_e;
	 * 
	 * 
	 * private static final int[] slots_top = new int[] {0}; private static
	 * final int[] slots_bottom = new int[] {2, 1}; private static final int[]
	 * slots_sides = new int[] {1};
	 * 
	 * private ItemStack[] campfireItemStacks = new ItemStack[3]; public int
	 * campfireBurnTime; public int currentItemBurnTime; public int
	 * campfireCookTime;
	 * 
	 * public int getSizeInventory() { return this.campfireItemStacks.length; }
	 * 
	 * public ItemStack getStackInSlot(int par1) { return
	 * this.campfireItemStacks[par1]; }
	 * 
	 * public ItemStack decrStackSize(int par1, int par2) { if
	 * (this.campfireItemStacks[par1] != null) { ItemStack itemstack;
	 * 
	 * if (this.campfireItemStacks[par1].stackSize <= par2) { itemstack =
	 * this.campfireItemStacks[par1]; this.campfireItemStacks[par1] = null;
	 * return itemstack; } else { itemstack =
	 * this.campfireItemStacks[par1].splitStack(par2);
	 * 
	 * if (this.campfireItemStacks[par1].stackSize == 0) {
	 * this.campfireItemStacks[par1] = null; }
	 * 
	 * return itemstack; } } else { return null; } }
	 * 
	 * public ItemStack getStackInSlotOnClosing(int par1) { if
	 * (this.campfireItemStacks[par1] != null) { ItemStack itemstack =
	 * this.campfireItemStacks[par1]; this.campfireItemStacks[par1] = null;
	 * return itemstack; } else { return null; } }
	 * 
	 * public void setInventorySlotContents(int par1, ItemStack par2ItemStack) {
	 * this.campfireItemStacks[par1] = par2ItemStack;
	 * 
	 * if (par2ItemStack != null && par2ItemStack.stackSize >
	 * this.getInventoryStackLimit()) { par2ItemStack.stackSize =
	 * this.getInventoryStackLimit(); } }
	 * 
	 * public void readFromNBT(NBTTagCompound par1NBTTagCompound) {
	 * super.readFromNBT(par1NBTTagCompound); NBTTagList nbttaglist =
	 * par1NBTTagCompound.getTagList("Items"); this.campfireItemStacks = new
	 * ItemStack[this.getSizeInventory()];
	 * 
	 * for (int i = 0; i < nbttaglist.tagCount(); ++i) { NBTTagCompound
	 * nbttagcompound1 = (NBTTagCompound)nbttaglist.tagAt(i); byte b0 =
	 * nbttagcompound1.getByte("Slot");
	 * 
	 * if (b0 >= 0 && b0 < this.campfireItemStacks.length) {
	 * this.campfireItemStacks[b0] =
	 * ItemStack.loadItemStackFromNBT(nbttagcompound1); } }
	 * 
	 * this.campfireBurnTime = par1NBTTagCompound.getShort("BurnTime");
	 * this.campfireCookTime = par1NBTTagCompound.getShort("CookTime");
	 * this.currentItemBurnTime = getItemBurnTime(this.campfireItemStacks[1]);
	 * 
	 * if (par1NBTTagCompound.hasKey("CustomName")) { this.field_94130_e =
	 * par1NBTTagCompound.getString("CustomName"); } }
	 * 
	 * public void writeToNBT(NBTTagCompound par1NBTTagCompound) {
	 * super.writeToNBT(par1NBTTagCompound);
	 * par1NBTTagCompound.setShort("BurnTime", (short)this.campfireBurnTime);
	 * par1NBTTagCompound.setShort("CookTime", (short)this.campfireCookTime);
	 * NBTTagList nbttaglist = new NBTTagList();
	 * 
	 * for (int i = 0; i < this.campfireItemStacks.length; ++i) { if
	 * (this.campfireItemStacks[i] != null) { NBTTagCompound nbttagcompound1 =
	 * new NBTTagCompound(); nbttagcompound1.setByte("Slot", (byte)i);
	 * this.campfireItemStacks[i].writeToNBT(nbttagcompound1);
	 * nbttaglist.appendTag(nbttagcompound1); } }
	 * 
	 * par1NBTTagCompound.setTag("Items", nbttaglist);
	 * 
	 * if (this.isInvNameLocalized()) {
	 * par1NBTTagCompound.setString("CustomName", this.field_94130_e); } }
	 * 
	 * public int getInventoryStackLimit() { return 64; }
	 * 
	 * @SideOnly(Side.CLIENT) public int getCookProgressScaled(int par1) {
	 * return this.campfireCookTime * par1 / 200; }
	 * 
	 * @SideOnly(Side.CLIENT) public int getBurnTimeRemainingScaled(int par1) {
	 * if (this.currentItemBurnTime == 0) { this.currentItemBurnTime = 200; }
	 * 
	 * return this.campfireBurnTime * par1 / this.currentItemBurnTime; }
	 * 
	 * public boolean isBurning() { return this.campfireBurnTime > 0; }
	 * 
	 * public void updateEntity() { boolean flag = this.campfireBurnTime > 0;
	 * boolean flag1 = false;
	 * 
	 * if (this.campfireBurnTime > 0) { --this.campfireBurnTime; }
	 * 
	 * if (!this.worldObj.isRemote) { if (this.campfireBurnTime == 0 &&
	 * this.canSmelt()) { this.currentItemBurnTime = this.campfireBurnTime =
	 * getItemBurnTime(this.campfireItemStacks[1]);
	 * 
	 * if (this.campfireBurnTime > 0) { flag1 = true;
	 * 
	 * if (this.campfireItemStacks[1] != null) {
	 * --this.campfireItemStacks[1].stackSize;
	 * 
	 * if (this.campfireItemStacks[1].stackSize == 0) {
	 * this.campfireItemStacks[1] =
	 * this.campfireItemStacks[1].getItem().getContainerItemStack
	 * (campfireItemStacks[1]); } } } }
	 * 
	 * if (this.isBurning() && this.canSmelt()) { ++this.campfireCookTime;
	 * 
	 * if (this.campfireCookTime == 200) { this.campfireCookTime = 0;
	 * this.smeltItem(); flag1 = true; } } else { this.campfireCookTime = 0; }
	 * 
	 * if (flag != this.campfireBurnTime > 0) { flag1 = true;
	 * BlockCampfire.updateCampfireBlockState(this.campfireBurnTime > 0,
	 * this.worldObj, this.xCoord, this.yCoord, this.zCoord); } }
	 * 
	 * if (flag1) { this.onInventoryChanged(); } }
	 * 
	 * private boolean canSmelt() { if (this.campfireItemStacks[0] == null) {
	 * return false; } else { ItemStack itemstack =
	 * FurnaceRecipes.smelting().getSmeltingResult(this.campfireItemStacks[0]);
	 * if (itemstack == null) return false; if (this.campfireItemStacks[2] ==
	 * null) return true; if
	 * (!this.campfireItemStacks[2].isItemEqual(itemstack)) return false; int
	 * result = campfireItemStacks[2].stackSize + itemstack.stackSize; return
	 * (result <= getInventoryStackLimit() && result <=
	 * itemstack.getMaxStackSize()); } }
	 * 
	 * public void smeltItem() { if (this.canSmelt()) { ItemStack itemstack =
	 * FurnaceRecipes.smelting().getSmeltingResult(this.campfireItemStacks[0]);
	 * 
	 * if (this.campfireItemStacks[2] == null) { this.campfireItemStacks[2] =
	 * itemstack.copy(); } else if
	 * (this.campfireItemStacks[2].isItemEqual(itemstack)) {
	 * campfireItemStacks[2].stackSize += itemstack.stackSize; }
	 * 
	 * --this.campfireItemStacks[0].stackSize;
	 * 
	 * if (this.campfireItemStacks[0].stackSize <= 0) {
	 * this.campfireItemStacks[0] = null; } } }
	 * 
	 * public static int getItemBurnTime(ItemStack par0ItemStack) { if
	 * (par0ItemStack == null) { return 0; } else { int i =
	 * par0ItemStack.getItem().itemID; Item item = par0ItemStack.getItem();
	 * 
	 * if (par0ItemStack.getItem() instanceof ItemBlock && Block.blocksList[i]
	 * != null) { Block block = Block.blocksList[i];
	 * 
	 * if (block == Block.woodSingleSlab) { return 150; }
	 * 
	 * if (block.blockMaterial == Material.wood) { return 300; }
	 * 
	 * if (block == Block.coalBlock) { return 16000; } }
	 * 
	 * if (item instanceof ItemTool && ((ItemTool)
	 * item).getToolMaterialName().equals("WOOD")) return 200; if (item
	 * instanceof ItemSword && ((ItemSword)
	 * item).getToolMaterialName().equals("WOOD")) return 200; if (item
	 * instanceof ItemHoe && ((ItemHoe) item).getMaterialName().equals("WOOD"))
	 * return 200; if (i == Item.stick.itemID) return 100; if (i ==
	 * Item.coal.itemID) return 1600; if (i == Item.bucketLava.itemID) return
	 * 20000; if (i == Block.sapling.blockID) return 100; if (i ==
	 * Item.blazeRod.itemID) return 2400; return
	 * GameRegistry.getFuelValue(par0ItemStack); } }
	 * 
	 * public static boolean isItemFuel(ItemStack par0ItemStack) { return
	 * getItemBurnTime(par0ItemStack) > 0; }
	 * 
	 * public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer) { return
	 * this.worldObj.getBlockTileEntity(this.xCoord, this.yCoord, this.zCoord)
	 * != this ? false : par1EntityPlayer.getDistanceSq((double)this.xCoord +
	 * 0.5D, (double)this.yCoord + 0.5D, (double)this.zCoord + 0.5D) <= 64.0D; }
	 * 
	 * public void openChest() {}
	 * 
	 * public void closeChest() {}
	 * 
	 * public boolean isItemValidForSlot(int par1, ItemStack par2ItemStack) {
	 * return par1 == 2 ? false : (par1 == 1 ? isItemFuel(par2ItemStack) :
	 * true); }
	 * 
	 * public int[] getAccessibleSlotsFromSide(int par1) { return par1 == 0 ?
	 * slots_bottom : (par1 == 1 ? slots_top : slots_sides); }
	 * 
	 * public boolean canInsertItem(int par1, ItemStack par2ItemStack, int par3)
	 * { return this.isItemValidForSlot(par1, par2ItemStack); }
	 * 
	 * public boolean canExtractItem(int par1, ItemStack par2ItemStack, int
	 * par3) { return par3 != 0 || par1 != 1 || par2ItemStack.itemID ==
	 * Item.bucketEmpty.itemID; } /*
	 */
}
